//
//  Listener.swift
//  NetAction
//
//  Created by zcj on 2024/12/27.
//  description： 主要是管理connection，初步的数据处理，然后将数据交由其他类来实现
import Foundation
import Network


public class Listener:TCPListenDelegate{
    //存放connection的容器
    public var conDic : Dictionary<Int64,ConnectionMsg> = Dictionary()
    var connectionTimer:Timer?
    var tcpListen:TCPListen
    var dealDataDlg:DealNetDataProtocol
    
    public init(port: UInt16, sta: Int32,dnpdlg:DealNetDataProtocol){
        tcpListen = TCPListen(port: port, sta: sta)
        dealDataDlg = dnpdlg
    }
    
    public func start(){
        tcpListen.delegate = self
        tcpListen.start()
    }
    
    public func receiveConAndData(connection: NWConnection, data: Data) {
        let id = self.getConnectionId(con: connection)
        var finData = data
       
        if  let conMsg = conDic[id] {
            conMsg.update()
            conMsg.lastData.append(data)
            finData = conMsg.lastData
            conMsg.lastData = Data()
        }else{
           let newConMsg = ConnectionMsg(con: connection)
            conDic[id] = newConMsg
        }
        
        //交给其他的类去实现更加细致的处理。
        dealDataDlg.receiveData(id: id, data: finData)
        
    }
    
    //实现对于connection 的hash值获取,作为id
    func getConnectionId(con:NWConnection) -> Int64{
        let id = Cal.hashObIden(iden: ObjectIdentifier(con))
        return id
    }
    
    public func ListenReady() {
        self.monitorConnectionWithTimer()//监视连接的最后通信时间
        self.monitorNetwork()//监视网络是否断开
    }
    
    public func ListenFailed() {
        self.connectionTimer?.invalidate()
    }
    
  
    //#####################################
    //定时监视connection的生命周期
    func monitorConnectionWithTimer(){
        self.connectionTimer = Timer(timeInterval: 3, repeats: true, block: { Timer in
            self.closeConnectionTimeOut()
        })
        if self.connectionTimer != nil{
            RunLoop.main.add(self.connectionTimer!, forMode: .common)
        }
    }
    
    
    //主动关闭连接
    func closeConnectionTimeOut(){
        //如果间隔最后一次发送信息的时间超过了timeout分钟就断开连接
        let timeoutLine:TimeInterval = Date().timeIntervalSince1970 - setting.timeout
        let arr = conDic.keys
        for key in arr{
            if conDic[key]!.timeStamp < timeoutLine{
                //关闭connection
                self.closeConnection(id: key)
            }
        }
    }
    
    func closeConnection(id:Int64){
        if let cm = conDic[id]{
            cm.con.cancel()
            conDic.removeValue(forKey: id)
        }
    }
    //#####################################
    func monitorNetwork(){
        // 启动 NWPathMonitor 监控网络状态
        var pathMonitor = NWPathMonitor()
        pathMonitor.pathUpdateHandler = { path in
            if path.status == .satisfied {
                print("Network is available")
            } else {
                //网络断开
                print("Network is not available")
                self.connectionTimer?.invalidate()
                self.conDic.forEach { (key: Int64, value: ConnectionMsg) in
                    self.conDic.removeValue(forKey: key)
                }
            }
        }
        pathMonitor.start(queue: .global())
    }
}
